package com.warmheart.controller.main;

import java.util.HashMap;
import java.util.Map;
import java.util.regex.Pattern;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import cn.hutool.core.util.RandomUtil;
import com.warmheart.base.config.RedisService;
import com.warmheart.core.constant.RedisConstant;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.warmheart.base.annotation.Auth;
import com.warmheart.base.annotation.Duplicate;
import com.warmheart.base.controller.BaseController;
import com.warmheart.base.entity.LoginUser;
import com.warmheart.base.entity.Operator;
import com.warmheart.base.session.SessionLocalUtils;
import com.warmheart.base.session.SessionManager;
import com.warmheart.core.enums.ResultCode;
import com.warmheart.core.ex.BusinessException;
import com.warmheart.core.result.CommonResult;
import com.warmheart.core.util.ParamMapUtil;
import com.warmheart.core.util.RandomUtils;
import com.warmheart.entity.user.UserLogin;
import com.warmheart.model.VerifiedResultModel;
import com.warmheart.service.sys.ISysConfigService;
import com.warmheart.service.user.IUserLoginService;

@RestController
@RequestMapping("/main")
public class LoginController extends BaseController {

    private static Logger logger = LoggerFactory.getLogger(BaseController.class);

    @Autowired(required = false)
    private IUserLoginService userLoginService;

    @Autowired(required = false)
    private ISysConfigService sysConfigService;

    @Autowired(required = false)
    private SessionManager sessionManager;

//    @Autowired
//    private RedisService redisService;
//
//    //发送验证码
//    @PostMapping("/code")
//    public CommonResult<Map<String, Object>> code(HttpServletRequest request, HttpServletResponse response) throws Exception {
//        Map<String, Object> resultMap = new HashMap<String, Object>();
//        Map<String, Object> jsonMap = getJsonMap(request);
//
//        final String loginName = ParamMapUtil.getString(jsonMap, "loginName");
//
//        // 登录名不可为空
//        if (StringUtils.isBlank(loginName)) {
//            return CommonResult.failed(ResultCode.PARAM_EMPTY, "登录名不可为空");
//        }
//
//        // 判断登录名是否正常
//        if (loginName.length() != 11) {
//            return CommonResult.failed(ResultCode.PARAM_INVALID, "登录名格式不正确");
//        }
//        Pattern userPhonePattern = Pattern.compile("^([1]([3-9])[0-9]{9})$");
//        boolean userPhonePatternCheckResult = userPhonePattern.matcher(loginName).matches();
//        if (!userPhonePatternCheckResult) {
//            return CommonResult.failed(ResultCode.PARAM_INVALID, "登录名格式不正确");
//        }
//
//        //生成验证码
//        String code= RandomUtil.randomNumbers(6);
//
//        redisService.set(RedisConstant.REGISTER_SMS_CODE + loginName, code);
//
//        resultMap.put("code", code);
//
//        return CommonResult.success("获取验证码成功", resultMap);
//
//    }


    /**
     * 登录验证
     * 
     * @param request
     * @param response
     * @return
     * @throws Exception
     */
    @RequestMapping("/login")
    public CommonResult<Map<String, Object>> login(HttpServletRequest request, HttpServletResponse response)
            throws Exception {
        Map<String, Object> resultMap = new HashMap<String, Object>();
        Map<String, Object> jsonMap = getJsonMap(request);


        // TODO 具体实现，比如APP端使用手机+验证码登录
        // APP端使用手机+验证码登录伪代码
        final String loginName = ParamMapUtil.getString(jsonMap, "loginName");

        // 登录名不可为空
        if (StringUtils.isBlank(loginName)) {
            return CommonResult.failed(ResultCode.PARAM_EMPTY, "登录名不可为空");
        }

        // 判断登录名是否正常
        if (loginName.length() != 11) {
            return CommonResult.failed(ResultCode.PARAM_INVALID, "登录名格式不正确");
        }
        Pattern userPhonePattern = Pattern.compile("^([1]([3-9])[0-9]{9})$");
        boolean userPhonePatternCheckResult = userPhonePattern.matcher(loginName).matches();
        if (!userPhonePatternCheckResult) {
            return CommonResult.failed(ResultCode.PARAM_INVALID, "登录名格式不正确");
        }

        // 验证码不可为空
        String smsCode = ParamMapUtil.getString(jsonMap, "smsCode");
        if (StringUtils.isBlank(smsCode)) {
            return CommonResult.failed(ResultCode.PARAM_EMPTY, "验证码不可为空");
        }


        VerifiedResultModel verifiedResult = this.userLoginService.verifyLoginSmsCode(loginName, smsCode);
        if (!verifiedResult.getVerifyFlag()) {
            return CommonResult.failed(ResultCode.PARAM_INVALID, verifiedResult.getVerifyMsg());
        }

        // 判断登录用户是否合法
        UserLogin checkMember = new UserLogin();
        checkMember.setLoginName(loginName);
        checkMember.setClientType("03");
        checkMember.setLoginType("01");
        checkMember = this.userLoginService.selectOne(checkMember);

        // 用户不存在
        if (checkMember == null) {
            // TODO 具体实现，比如直接注册
            // 直接注册伪代码
            try {
                this.userLoginService.register(loginName);
            } catch (BusinessException ex) {
                // 业务异常直接抛出，交给切面处理
                throw ex;
            } catch (Exception e) {
                logger.error("保存用户注册信息异常", e);
                return CommonResult.failed(ResultCode.BUSINESS_ERROR, "登录异常");
            }
            // 重新获取登录信息
            checkMember = new UserLogin();
            checkMember.setLoginName(loginName);
            checkMember.setLoginType("01");
            checkMember = this.userLoginService.selectOne(checkMember);
        }

        // 保存登录信息
        LoginUser checkLoginUser = new LoginUser();
        checkLoginUser.setUserId(checkMember.getUserId());
        checkLoginUser.setLoginName(checkMember.getLoginName());
        // TODO 伪代码，具体由用户主表提供
        String userNo = RandomUtils.getRandomString(8);
        checkLoginUser.setUserNo(userNo);

        // 保存登录信息实体类
        Operator operator = new Operator();
        operator.setLoginUser(checkLoginUser);

        // 保存登录信息
        String token = sessionManager.setOperator(operator);
        // 存入本服务器缓存中，用于提高访问速度
        SessionLocalUtils.setOperator(operator);
        resultMap.put("token", token);

        // 保存登录记录
        mdcThreadPoolTaskExecutor.execute(new Runnable() {

            @Override
            public void run() {
                // TODO 可以在这里添加登录记录
            }
        });

        return CommonResult.success("登录成功", resultMap);
    }

    /**
     * 退出登录
     * 
     * @param request
     * @return
     * @throws Exception
     */
    @Auth(verifyLogin = true)
    @Duplicate(validate = true)
    @RequestMapping("/logout")
    public CommonResult<Map<String, Object>> logout(HttpServletRequest request, HttpServletResponse response)
            throws Exception {
        // 清除REDIS存储的用户数据
        sessionManager.delOperator(request);
        return CommonResult.success("退出登录");
    }
}
